/*
 * Originally modified by Lin, sent as an attachment in an email
 * Modified by Seth to fix segfault bugs
 *
 * sync.h
 */

#ifndef _STHREAD_SYNC_H_
#define _STHREAD_SYNC_H_

#include "sthread.h"

typedef struct my_queue_struct{
		 sthread_t thread;
		 struct my_queue_struct * next;
}queue_t;

typedef struct sthread_sem_struct{
		int count;
		unsigned long guard; //mutex to control access to sem variables and sem->queue variables
		struct my_queue_struct * queue;
}Semaphore;

int sthread_semaphore_init(Semaphore *s, int count);
int sthread_semaphore_destroy(Semaphore *s);
int sthread_semaphore_down(Semaphore *s);
int sthread_semaphore_try_down(Semaphore *s);
int sthread_semaphore_up(Semaphore *s);


typedef struct sthread_rwlock_struct {
	Semaphore OkToRead;
	Semaphore OkToWrite;
	Semaphore Lock;
	int active_readers;
	int waiting_readers;
	int active_writers;
	int waiting_writers;

}sthread_rwlock_t;

int sthread_rwlock_init(sthread_rwlock_t *rwlock);
int sthread_rwlock_destroy(sthread_rwlock_t *rwlock);
int sthread_read_lock(sthread_rwlock_t *rwlock);
int sthread_read_try_lock(sthread_rwlock_t *rwlock);
int sthread_read_unlock(sthread_rwlock_t *rwlock);
int sthread_write_lock(sthread_rwlock_t *rwlock);
int sthread_write_try_lock(sthread_rwlock_t *rwlock);
int sthread_write_unlock(sthread_rwlock_t *rwlock);

#endif
